home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / comp0_89.lha / Feel / Boot / CBoot / gen-init.em < prev    next >
Lisp/Scheme  |  1993-07-28  |  49KB  |  1,525 lines

  1. ;; Eulisp Module
  2. ;; Author: pab
  3. ;; File: gen-init.em
  4. ;; Date: Fri Dec 11 19:36:46 1992
  5. ;;
  6. ;; Project:
  7. ;; Description:
  8. ;;  Creates the initialisation program from
  9. ;;  Defclasses, etc
  10.  
  11. (defmodule gen-init
  12.   ((except (scan-args required-argument unbound-argument null-argument default-argument unbound-slot-value) standard0)
  13.    list-fns
  14.    class-macs
  15.    class-defs
  16.    )
  17.   ()
  18.  
  19.   (defconstant unbound-slot-value '%_*unbound*_%)
  20.  
  21.   (defun scan-args (arg init-lst panic)
  22.     (labels ((scan-aux (arg lst)
  23.                (if (null lst)
  24.                (panic arg init-lst)
  25.              (if (eq (car lst) arg)
  26.                  (car (cdr lst))
  27.                (scan-aux arg (cdr (cdr lst)))))))
  28.         (scan-aux arg init-lst)))
  29.  
  30.   (defun required-argument (arg args)
  31.     (error "Missing init-argument" Internal-Error 'error-value (cons arg args)))
  32.  
  33.   (defun unbound-argument (arg args)
  34.     unbound-slot-value)
  35.  
  36.   (defun null-argument (arg args)
  37.     nil)
  38.  
  39.   (defun default-argument (x)
  40.     (lambda (arg args) x))
  41.  
  42.  
  43.   (defun make-boot-code (flag)
  44.     (setq *init-type* flag)
  45.     (let ((classlist (the-classlist)))
  46.       `(defmodule init
  47.      ,(init-modules)
  48.      ()
  49.      (expose ,@(init-modules))
  50.      ,@(un-progn
  51.         `(progn (progn ,@(preprocess-forms (make-initial-constants classlist)))
  52.  
  53.            (progn ,@(preprocess-forms (make-class-hierarchy classlist)))
  54.  
  55.            (progn ,@(preprocess-forms (make-slot-descriptions classlist)))
  56.  
  57.            (progn ,(preprocess-forms (make-slot-accessors classlist)))
  58.  
  59.            (progn ,@(preprocess-forms-2 (method-initialisation-code classlist)))
  60.            ))
  61.      )))
  62.  
  63.   (defun write-std-code ()
  64.     ...)
  65.  
  66.   (defun write-nl (x y)
  67.     (write x y)
  68.     (newline y))
  69.  
  70.   (defun write-i-code ()
  71.     (let ((code (make-boot-code 'interpreted))
  72.       (file (open "init.em" 'output )))
  73.       (print "(" file)
  74.       (mapc (lambda (x) (write-nl x file))
  75.         code)
  76.       (print ")" file)
  77.       (close file)))
  78.  
  79.   (defun write-c-code ()
  80.     (let ((code (make-boot-code 'compiled))
  81.       (file (open "init.em" 'output t)))
  82.       (print "(" file)
  83.       (mapc (lambda (x) (write-nl x file))
  84.         code)
  85.       (print ")" file)
  86.       (close file)))
  87.  
  88.   (defconstant slot-reffers
  89.     #(primitive-slot-ref-0
  90.       primitive-slot-ref-1
  91.       primitive-slot-ref-2
  92.       primitive-slot-ref-3
  93.       primitive-slot-ref-4
  94.       primitive-slot-ref-5
  95.       primitive-slot-ref-6
  96.       primitive-slot-ref-7
  97.       primitive-slot-ref-8
  98.       primitive-slot-ref-9) )
  99.  
  100.   (defconstant slot-setters
  101.     #(primitive-set-slot-ref-0
  102.       primitive-set-slot-ref-1
  103.       primitive-set-slot-ref-2
  104.       primitive-set-slot-ref-3
  105.       primitive-set-slot-ref-4
  106.       primitive-set-slot-ref-5
  107.       primitive-set-slot-ref-6
  108.       primitive-set-slot-ref-7
  109.       primitive-set-slot-ref-8
  110.       primitive-set-slot-ref-9) )
  111.  
  112.   (deflocal *init-type* 'interpreted)
  113.  
  114.   (defun init-for-compile-p ()
  115.     (eq *init-type* 'compiled))
  116.  
  117.   (defun init-for-interpret-p ()
  118.     (eq *init-type* 'interpreted))
  119.  
  120.   '(defun mapcan (f l)
  121.     (if (atom l) nil
  122.       (nconc (f (car l))
  123.          (mapcan f (cdr l)))))
  124.   (print mapcan)
  125.  
  126.   (defun un-progn (form)
  127.     (cond ((null form) nil)
  128.       ((eq (car form) 'progn)
  129.        (mapcan un-progn (cdr form)))
  130.       (t (list form))))
  131.  
  132.   (defun my-mapcar (fn lst)
  133.     (if (atom lst) (fn lst)
  134.       (cons (fn (car lst))
  135.         (my-mapcar fn (cdr lst)))))
  136.  
  137.   (defun preprocess-forms (form)
  138.     (cond ((atom form) form)
  139.       ((eq (car form) 'quote)
  140.        form)
  141.       ((and (eq (car form) 'setter)
  142.         (eq (cadr form) 'car))
  143.        'primitive-set-slot-ref-0 )
  144.       ((and (eq (car form) 'setter)
  145.         (eq (cadr form) 'cdr))
  146.        'primitive-set-slot-ref-1)
  147.       ((and (eq (car form) 'setter)
  148.         (accessor-location (cadr form)))
  149.        (vector-ref slot-setters (accessor-location (cadr form))))
  150.       ((accessor-location (car form))
  151.        (cons (vector-ref slot-reffers (accessor-location (car form)))
  152.          (preprocess-forms (cdr form))))
  153.       ((eq (car form) 'lambda)
  154.        (cons 'lambda (cons (cadr form)
  155.                    (preprocess-forms (cddr form)))))
  156.       ;; interpreter only macroexpansions
  157.       ((and (eq (car form) 'let)
  158.         (init-for-interpret-p))
  159.        (preprocess-forms
  160.         `((lambda ,(mapcar car (cadr form))
  161.         ,@(cddr form))
  162.           ,@(mapcar cadr (cadr form)))))
  163.       ((and (eq (car form) 'labels)
  164.         (init-for-interpret-p))
  165.        (preprocess-forms
  166.         `(let ,(mapcar (lambda (fn) (list (car fn) nil)) (cadr form))
  167.            ,@(mapcar (lambda (fn)
  168.               `(setq ,(car fn) (lambda ,@(cdr fn))))
  169.             (cadr form))
  170.            ,@(cddr form))))
  171.       ((eq (car form) 'method-lambda)
  172.        (preprocess-forms
  173.         `(lambda (,@(method-extra-args) ,@(cadr form))
  174.            ,@(cddr form))))
  175.       ((eq (car form) 'compile-time)
  176.        (cond ((eq *init-type* 'interpreted)
  177.           nil)
  178.          ((eq *init-type* 'compiled)
  179.           (cons 'progn (preprocess-forms (cdr form))))))
  180.       ((eq (car form) 'interpret-time)
  181.        (cond ((init-for-compile-p)
  182.           nil)
  183.          ((init-for-interpret-p)
  184.           (cons 'progn (preprocess-forms (cdr form))))))
  185.       (t (my-mapcar preprocess-forms form))))
  186.  
  187.   (defun preprocess-forms-2 (form)
  188.     (cond ((atom form) form)
  189.       ((eq (car form) 'quote)
  190.        form)
  191.       ((and (eq (car form) 'setter)
  192.         (eq (cadr form) 'car))
  193.        'primitive-set-slot-ref-0 )
  194.       ((and (eq (car form) 'setter)
  195.         (eq (cadr form) 'cdr))
  196.        'primitive-set-slot-ref-1)
  197.       ;; interpreter only macroexpansions
  198.       ((eq (car form) 'lambda)
  199.        (cons 'lambda (cons (cadr form)
  200.                    (preprocess-forms-2 (cddr form)))))
  201.       ((and (eq (car form) 'let)
  202.         (init-for-interpret-p))
  203.        (preprocess-forms-2
  204.         `((lambda ,(mapcar car (cadr form))
  205.         ,@(cddr form))
  206.           ,@(mapcar cadr (cadr form)))))
  207.       ((and (eq (car form) 'labels)
  208.         (init-for-interpret-p))
  209.        (preprocess-forms-2
  210.         `(let ,(mapcar (lambda (fn) (list (car fn) nil)) (cadr form))
  211.            ,@(mapcar (lambda (fn)
  212.               `(setq ,(car fn) (lambda ,@(cdr fn))))
  213.             (cadr form))
  214.            ,@(cddr form))))
  215.       ((eq (car form) 'method-lambda)
  216.        (preprocess-forms-2
  217.         `(lambda (,@(method-extra-args) ,@(cadr form))
  218.            ,@(cddr form))))
  219.       ((and (eq (car form) 'call-next-method)
  220.         (init-for-interpret-p))
  221.        '(if  ***method-status-handle***
  222.          (progn ;;(format t "Call next: ~a ~a\n"
  223.            ;;***method-status-handle***
  224.            ;;     ***method-args-handle***)
  225.            (call-method-by-list
  226.              ***method-status-handle***
  227.              ***method-args-handle***))
  228.           (error "No Next Method" <Internal-Error> nil)))
  229.       ((eq (car form) 'compile-time)
  230.        (cond ((init-for-interpret-p)
  231.           nil)
  232.          ((init-for-compile-p)
  233.           (cons 'progn (preprocess-forms-2 (cdr form))))))
  234.       ((eq (car form) 'interpret-time)
  235.        (cond ((init-for-compile-p)
  236.           nil)
  237.          ((init-for-interpret-p)
  238.           (cons 'progn (preprocess-forms-2 (cdr form))))))
  239.       (t (my-mapcar preprocess-forms-2 form))))
  240.  
  241.   (defun method-extra-args ()
  242.     (if (init-for-interpret-p)
  243.     (list '***method-status-handle*** '***method-args-handle***)
  244.       nil))
  245.  
  246.   (defun make-initial-constants (classlist)
  247.     (mapcar (lambda (classd)
  248.           (let ((name (scan-args 'name classd (default-argument 'anonymous))))
  249.         (print (list name (scan-args 'allocate classd null-argument)))
  250.         `(progn ,@(if (scan-args 'allocate classd null-argument)
  251.                   `((defconstant ,name (allocate-object <class>)))
  252.                 ())
  253.             (export ,name)
  254.             (set-class-of ,name ,(scan-args 'metaclass classd (default-argument '<class>))))))
  255.         classlist))
  256.  
  257.   (defun make-class-fill-list (classlist)
  258.     (cons 'list (mapcar (lambda (classd)
  259.               (let ((cpl (find-class-precedence-list classd)))
  260.                 `(list ,(scan-args 'name classd required-argument)
  261.                    ',(scan-args 'name classd required-argument)
  262.                    ,(find-class-size cpl)
  263.                    ',(find-class-initargs cpl)
  264.                    (list ,@(scan-args 'direct-superclasses classd null-argument))
  265.                    (list ,@(mapcar (lambda (classd)
  266.                              (scan-args 'name classd required-argument))
  267.                            cpl))
  268.                    )))
  269.             classlist)))
  270.  
  271.   (defun find-class-size (class-prec-list)
  272.     (fold (lambda (classd n)
  273.         (+ n
  274.            (length (scan-args 'direct-slot-descriptions classd
  275.                   required-argument))))
  276.       class-prec-list
  277.       0))
  278.  
  279.   (defun find-class-initargs (cpl)
  280.     (fold (lambda (classd inits)
  281.         (append (scan-args 'direct-initargs classd null-argument)
  282.             inits))
  283.       cpl
  284.       nil))
  285.  
  286.   ;; assume single inheritance
  287.   (defun find-class-precedence-list (classd)
  288.     (cons classd
  289.       (let ((supers (scan-args 'direct-superclasses classd required-argument)))
  290.         (if (null supers) nil
  291.           (find-class-precedence-list (find-class (car supers)))))))
  292.  
  293.  
  294.   ;; lst -> (progn (defconstant accessor (make-prim-accessor ...)) ...)
  295.   (defun make-slot-accessors (classlist)
  296.     (cons 'progn
  297.       (mapcar (lambda (classd)
  298.             (let ((name (scan-args 'name classd required-argument)))
  299.               `(progn ,@(mapcar (lambda (slotd)
  300.                      (let ((accessor (scan-args 'accessor slotd null-argument)))
  301.                        (if (null accessor) nil
  302.                          `(progn (defconstant ,accessor
  303.                                (simple-find-accessor ,name
  304.                                           ',(scan-args 'name slotd
  305.                                                    required-argument)))
  306.                              (export ,accessor)))))
  307.                        (scan-args 'direct-slot-descriptions classd null-argument)))))
  308.           classlist)))
  309.  
  310.  
  311.   ;;
  312.   ;; Code starts here
  313.   ;;
  314.   (defconstant *interpret-init-modules*
  315.     '(arith bci
  316.       lists  classes
  317.       sockets streams ccc symbols strings calls others
  318.       tables  vectors
  319.       (except (error cerror)
  320.           errors)
  321.       (only (set-compute-and-apply-fn generic-function-p methodp call-method-by-list) generics)
  322.       class-names
  323.       ))
  324.  
  325.   (defconstant *compile-init-modules*
  326.     '(arith bci
  327.        ;;lists
  328.       (except (car cdr cons list append nconc memq null consp mapcar mapc atom) lists)
  329.       (only (class-of set-type set-class-of allocate-object subclassp
  330.               make-structure-reader
  331.               make-structure-writer
  332.               initialize-local-slots
  333.               allocate initialize primitive-slot-ref primitive-set-slot-ref) 
  334.         classes)
  335.       sockets streams
  336.       (except (eq) ccc )
  337.       symbols strings 
  338.       (except (atom) others)
  339.       (except (apply) calls)
  340.       tables
  341.       (except (vector-ref) vectors)
  342.       (except (error cerror)
  343.           errors)
  344.       (only (set-compute-and-apply-fn generic-function-p methodp ) generics)
  345.       class-names
  346.       boot
  347.       ))
  348.  
  349.   (defun init-modules ()
  350.     (if (init-for-interpret-p)
  351.     *interpret-init-modules*
  352.       *compile-init-modules*))
  353.  
  354.  
  355.   ;; Fill-list is:
  356.   ;; name size initargs supers
  357.  
  358.   (defconstant class-hierarchy-literals
  359.     '(
  360.  
  361.       (interpret-time
  362.         (defconstant mapcar1 mapcar)
  363.     (defconstant mapc1 mapc))
  364.  
  365.       ;; Copied from  internals --- do not change!
  366.       (defconstant unbound-slot-value '%_*unbound*_%)
  367.       (export unbound-slot-value class-type)
  368.       (defconstant generic-type #xa4)
  369.       (defconstant method-type  #x25)
  370.       (defconstant class-type  #xd)
  371.  
  372.       (defun fill-class (class desc)
  373.     ;;(generic_generic_prin\,Object (car desc) nil)
  374.     ;;(newline nil)
  375.     ((setter class-name) class (car desc))
  376.     (setq desc (cdr desc))
  377.     ((setter class-instance-size) class (car desc))
  378.     (setq desc (cdr desc))
  379.     ((setter class-initargs) class (car desc))
  380.     (setq desc (cdr desc))
  381.     ((setter class-direct-superclasses) class (car desc))
  382.     (setq desc (cdr desc))
  383.     ((setter class-precedence-list) class (car desc))
  384.     (setq desc (cdr desc))
  385.     ((setter class-direct-subclasses) class nil)
  386.     (set-type class class-type)
  387.     (mapc1 (lambda (cl)
  388.         ((setter class-direct-subclasses) cl (cons class (class-direct-subclasses cl))))
  389.           (class-direct-superclasses class)))
  390.  
  391.       (defun initialise-hierarchy (lst)
  392.     (if (null lst) nil
  393.       (progn
  394.         (fill-class (car (car lst)) (cdr (car lst)))
  395.         (initialise-hierarchy (cdr lst)))))))
  396.  
  397.  
  398.   (defun make-class-hierarchy (classlist)
  399.     `(,@class-hierarchy-literals
  400.       (initialise-hierarchy ,(make-class-fill-list classlist))))
  401.  
  402. (defconstant make-slot-descriptions-literals
  403.     '(
  404.       ;;(generic_generic_prin\,Object "Done Class hierarchy\n" nil)
  405.       ;; add-method bootstrap...
  406.       (defun i-add1 (x)
  407.     (binary+_Integer x 1))
  408.  
  409.       (defun i-sub1 (x)
  410.     (binary-_Integer x 1))
  411.  
  412.       (defun i-zerop (x)
  413.     (binary=_Integer 0 x))
  414.  
  415.       (defun i-greaterp (x y)
  416.     (binary<_Integer y x))
  417.  
  418.       (defun fold (fn lst val)
  419.     (if (null lst) val
  420.       (fold fn (cdr lst)
  421.         (fn (car lst) val))))
  422.       (export fold )
  423.  
  424.       ;; should define cons as compile-inline...
  425.       (defun reverse (x)
  426.     (fold cons x nil))
  427.  
  428.       (defun assq (x lst)
  429.     (if (null lst) nil
  430.       (if (eq (car (car lst)) x)
  431.           (car lst)
  432.         (assq x (cdr lst)))))
  433.  
  434.       (defun identity (x) x)
  435.  
  436.       (defconstant slot-readers
  437.     (make-initialized-vector
  438.      primitive-slot-ref-0
  439.      primitive-slot-ref-1
  440.      primitive-slot-ref-2
  441.      primitive-slot-ref-3
  442.      primitive-slot-ref-4
  443.      primitive-slot-ref-5
  444.      primitive-slot-ref-6
  445.      primitive-slot-ref-7
  446.      primitive-slot-ref-8
  447.      primitive-slot-ref-9) )
  448.  
  449.       (defconstant slot-writers
  450.     (make-initialized-vector
  451.      primitive-set-slot-ref-0
  452.      primitive-set-slot-ref-1
  453.      primitive-set-slot-ref-2
  454.      primitive-set-slot-ref-3
  455.      primitive-set-slot-ref-4
  456.      primitive-set-slot-ref-5
  457.      primitive-set-slot-ref-6
  458.      primitive-set-slot-ref-7
  459.      primitive-set-slot-ref-8
  460.      primitive-set-slot-ref-9))
  461.  
  462.       
  463.       (defun %compute-reader (n)
  464.     (if (i-greaterp 10 n)
  465.         (vector-ref slot-readers n)
  466.       (method-lambda (x)
  467.              (primitive-slot-ref x n))))
  468.  
  469.       (defun %compute-writer (n)
  470.     (if (i-greaterp 10 n)
  471.         (vector-ref slot-writers n)
  472.       (method-lambda (x v)
  473.              (primitive-set-slot-ref x n v))))
  474.  
  475.       ;; Major data-structure --- method table implemented as a tree
  476.       (defun make-initial-table (key entry)
  477.     (mk-tab-aux key entry))
  478.  
  479.       (defun mk-tab-aux (key entry)
  480.     (labels ((add-part (lst tab)
  481.                (if (null lst) tab
  482.                  (add-part (cdr lst)
  483.                        (cons (cons (car lst) tab) nil)))))
  484.         (add-part (reverse key) entry)))
  485.  
  486.       (defun add-table-entry (table key value)
  487.     (if (null table)
  488.         (error "Can't happen" <Internal-Error>)
  489.       (let ((xx (assq (car key) table)))
  490.         (if (null xx)
  491.         (progn (nconc table
  492.                   (make-initial-table key value))
  493.                table)
  494.           (if (null (cdr key))
  495.           ;; replacement method
  496.           ((setter cdr) xx value)
  497.         (add-table-entry (cdr xx) (cdr key) value))))))
  498.       
  499.       ;; Make accessors look pretty...
  500.       (defun symbol-unbraced-name (sym)
  501.     (let ((x (symbol-name sym)))
  502.       (if (eq (string-ref x 0) #\<)
  503.           (substring x 1 (i-sub1 (i-sub1 (string-length x))))
  504.         x)))
  505.  
  506.       (export symbol-unbraced-name)
  507.       ;; General stuff for scan-args
  508.  
  509.       ;; XXX: Should be inline
  510.       (interpret-time
  511.        (defun scan-args (arg init-lst panic)
  512.      ;;(generic_generic_prin\,Object arg nil)
  513.      ;;(newline nil)
  514.      (labels ((scan-aux (arg lst)
  515.                 (if (null lst)
  516.                 (panic arg init-lst)
  517.                   (if (eq (car lst) arg)
  518.                   (car (cdr lst))
  519.                 (scan-aux arg (cdr (cdr lst)))))))
  520.          (scan-aux arg init-lst)))
  521.        )
  522.       (defun required-argument (arg args)
  523.     (error "Missing init-argument" <Internal-Error> 'error-value arg))
  524.  
  525.       (defun unbound-argument (arg args)
  526.     unbound-slot-value)
  527.  
  528.       (defun null-argument (arg args)
  529.     nil)
  530.  
  531.       (defun default-argument (x)
  532.     (lambda (arg args) x))
  533.  
  534.       (export required-argument unbound-argument null-argument default-argument scan-args)
  535.  
  536.       ;; find the right sort of lookup
  537.       (defun simple-compute-method-lookup-function (gf domain)
  538.     (lambda (args)
  539.       (find-applicable-methods gf args)))
  540.  
  541.  
  542.       (defun %generic-domain (gf)
  543.     (let ((dom (cdr (generic-method-description gf))))
  544.       (if dom dom
  545.           (let ((obj (list <object>)))
  546.         ((setter cdr) obj obj)
  547.         obj))))
  548.  
  549.       (defun method-signature-depth (gf meth)
  550.     (let ((sig (method-signature meth))
  551.           (domain (%generic-domain gf )))
  552.       (labels ((calc-depth (lst domain depth n)
  553.                    (if (null lst) depth
  554.                  (if (eq (car lst) (car domain))
  555.                      (calc-depth (cdr lst) (cdr domain) depth (i-add1 n))
  556.                    (calc-depth (cdr lst) (cdr domain) (i-add1 n) (i-add1 n))))))
  557.           (calc-depth sig domain 0 0))))
  558.  
  559.       ;; adds a method w/out any type-checking, or protocol.
  560.  
  561.       (defun simple-add-method (gf meth)
  562.     ;;(generic_generic_prin\,Object (list 'add-method (generic-name gf))
  563.     ;;  nil)
  564.     (let ((sig (method-signature meth))
  565.           (table (generic-method-table gf)))
  566.       (if (null table)
  567.           ((setter generic-method-table) gf (make-initial-table sig (list meth)))
  568.         (add-table-entry table sig (list meth)))
  569.       ((setter generic-fast-cache) gf nil)
  570.       ((setter generic-slow-cache) gf nil)
  571.       ((setter method-generic-function) meth gf)
  572.       (let ((true-depth (method-signature-depth gf meth)))
  573.         (if (i-greaterp true-depth (generic-discrimination-depth gf))
  574.         ((setter generic-discrimination-depth) gf true-depth)
  575.           nil))
  576.       gf))
  577.  
  578.       (defun std-generic-discriminator (gf lookup)
  579.     (lambda (args)
  580.       (let ((meths (lookup args)))
  581.         (if (null meths)
  582.         (error "No applicable method" no-applicable-method
  583.                'sig (mapcar1 class-of args))
  584.           (call-method-by-list meths args)))))
  585.  
  586.       (defun simple-make-generic args
  587.     ;;(generic_generic_prin\,Object "Make generic" nil)
  588.     ;;(generic_generic_prin\,Object args nil)
  589.     (let ((obj (allocate-object <generic-function>)))
  590.       ;;(generic_generic_prin\,Object obj nil)
  591.       ;;(newline nil)
  592.       ((setter generic-name) obj (scan-args 'name args required-argument))
  593.       ((setter generic-argtype) obj (scan-args 'argtype args required-argument))
  594.       ((setter generic-fast-cache) obj nil)
  595.       ((setter generic-slow-cache) obj nil)
  596.       ((setter generic-method-table) obj nil)
  597.       ((setter generic-method-description) obj 
  598.        (cons <method>
  599.          (scan-args 'domain args null-argument)))
  600.       (let ((lookup (simple-compute-method-lookup-function obj nil)))
  601.         ((setter generic-method-lookup-function) obj lookup)
  602.         ((setter generic-discriminator) obj (std-generic-discriminator obj lookup)))
  603.       ((setter generic-discrimination-depth) obj 0)
  604.       (set-type obj generic-type)
  605.       ;;(if (symbolp (%generic-name obj)) nil
  606.       ;;  (character-to-integer 'a))
  607.       obj))
  608.  
  609.       (defun simple-make-method args
  610.     ;;(generic_generic_prin\,Object "Make method" nil)
  611.     ;;(generic_generic_prin\,Object args nil)
  612.     (let ((meth (allocate-object <method>)))
  613.       ((setter method-qualifier) meth nil)
  614.       ((setter method-generic-function) meth nil)
  615.       ((setter method-signature) meth (scan-args 'signature args required-argument))
  616.       ((setter method-function) meth (scan-args 'function args required-argument))
  617.       ((setter method-fixed) meth (scan-args 'fixed args null-argument))
  618.       (set-type meth method-type)
  619.       meth))
  620.  
  621.  
  622.       (defun simple-compute-reader (cl args)
  623.     ;;(generic_generic_prin\,Object "Compute Reader" nil)
  624.     ;;(generic_generic_prin\,Object args nil)
  625.     (let ((pos (scan-args 'position args required-argument))
  626.           (gf (simple-make-generic
  627.            'argtype 1
  628.            'name (make-symbol
  629.               (string-append (symbol-unbraced-name (scan-args 'owner-class args (default-argument 'anonymous)))
  630.                      (string-append "-"
  631.                             (symbol-name (scan-args 'name args required-argument)))))))
  632.           )
  633.       (if (eq (scan-args 'class args null-argument) <unreadable-slot-description>)
  634.           (simple-add-method gf
  635.                  (simple-make-method
  636.                   'signature (list cl)
  637.                   'function (method-lambda (o)
  638.                                (error "Can't read slot" <Internal-Error>))))
  639.         ;; XXX: Should lookup lambda in a table --- there are only 13.
  640.         (simple-add-method gf
  641.                    (simple-make-method 'signature (list cl)
  642.                            'function (%compute-reader pos))))
  643.       gf))
  644.  
  645.  
  646.       (defun simple-compute-writer (cl args)
  647.     ;;(generic_generic_prin\,Object "Compute Writer" nil)
  648.     ;;(generic_generic_prin\,Object args nil)
  649.     (let ((pos (scan-args 'position args null-argument))
  650.           (gf (simple-make-generic
  651.            'argtype 2
  652.            'domain (list cl <object>)
  653.            'name (make-symbol
  654.               (string-append (string-append
  655.                       (symbol-name (scan-args 'owner-class args
  656.                                   (default-argument 'anonymous)))
  657.                       (string-append "-"
  658.                              (symbol-name (scan-args 'name args
  659.                                          required-argument))))
  660.                      "-setter"))))
  661.           )
  662.       (if (eq (scan-args 'class args null-argument) <unreadable-slot-description>)
  663.           (simple-add-method gf
  664.                  (simple-make-method
  665.                   'signature (list cl <object>)
  666.                   'function (method-lambda (o v)
  667.                                (error "Can't set slot" <Internal-Error> ))))
  668.         ;; XXX: Should lookup lambda in a table --- there are only 13.
  669.         (simple-add-method gf
  670.                    (simple-make-method
  671.                 'signature (list cl <object>)
  672.                      'function (%compute-writer pos))))
  673.       gf))
  674.  
  675.       ;; Okay, now make all those slots..
  676.  
  677.       (defun fill-slot-description (obj class args)
  678.     (let ((access-args (list 'class (car args)
  679.                  'owner-class (car (cdr args))
  680.                  'name  (car (cdr (cdr args)))
  681.                  'position (car (cdr (cdr (cdr args))))
  682.                  )))
  683.       (setq args (cdr (cdr  args)))
  684.       ((setter slot-description-name) obj (car args))
  685.       (setq args (cdr args))
  686.       ((setter slot-description-position) obj (car args))
  687.       (setq args (cdr args))
  688.       (let ((initform (car args)))
  689.         ((setter slot-description-initfunction) obj
  690.          (if (eq initform unbound-slot-value)
  691.          unbound-slot-value
  692.            (lambda () initform))))
  693.       (setq args (cdr args))
  694.       ((setter slot-description-initarg) obj (car args))
  695.       ((setter slot-description-slot-reader) obj
  696.        (simple-compute-reader class access-args))
  697.       ((setter slot-description-slot-writer) obj
  698.        (simple-compute-writer class access-args))
  699.       ;;(generic_generic_prin\,Object "Done slot" nil)
  700.       ;;(newline nil)
  701.       obj))
  702.  
  703.  
  704.       (defun simple-find-slot-description (class name)
  705.     (let ((xx (class-slot-descriptions class)))
  706.       (labels ((l1 (slots)
  707.                (if (null slots)
  708.                (error "Could not find slot" <Internal-Error> 'error-value name)
  709.              (if (eq (slot-description-name (car slots)) name)
  710.                  (car slots)
  711.                (l1 (cdr slots))))))
  712.           (l1 xx))))
  713.  
  714.       (defun simple-find-slot-reader (class slot-name)
  715.     (slot-description-slot-reader (simple-find-slot-description class slot-name)))
  716.  
  717.       (defun simple-find-slot-writer (class slot-name)
  718.     (slot-description-slot-writer (simple-find-slot-description class slot-name)))
  719.  
  720.       (defun simple-find-accessor (class slot-name)
  721.     (let ((reader (simple-find-slot-reader class slot-name))
  722.           (writer (simple-find-slot-writer class slot-name)))
  723.       ((setter generic-setter) reader writer)
  724.       reader))
  725.  
  726.  
  727.       (defun initialize-slots (lst)
  728.     (if (null lst) nil
  729.       (let ((class (car (car lst)))
  730.         (slots (cdr (car lst))))
  731.         ;;(generic_generic_prin\,Object (car lst) nil)
  732.         ((setter class-slot-descriptions) class
  733.          (append (if (null (class-direct-superclasses class)) nil
  734.                (class-slot-descriptions (car (class-direct-superclasses class))))
  735.              (make-slot-list class slots)))
  736.         ((setter class-local-slot-descriptions) class 
  737.          (mapcar1 (lambda (sd)
  738.             ;;(cons (slot-description-initarg sd)
  739.             ;; (slot-description-initfunction sd))
  740.             nil)
  741.              (class-slot-descriptions class)))
  742.         ((setter class-non-local-slot-descriptions) class (class-slot-descriptions class))
  743.         (initialize-slots (cdr lst)))))
  744.  
  745.       (defun make-slot-list (class slotds)
  746.     (if (null slotds) nil
  747.       (let ((slotd (car slotds))
  748.         (slot (allocate-object (car (car slotds)))))
  749.         ;;(generic_generic_prin\,Object slotd nil)
  750.         (fill-slot-description slot class (cons (car slotd) (cons (class-name class) (cdr slotd))))
  751.         (cons slot (make-slot-list class (cdr slotds))))))
  752.  
  753.       (defconstant internal-gf-setter-setter (setter generic-setter))
  754.       (defconstant internal-gf-setter primitive-slot-ref-9)
  755.       (defconstant internal-gf-method-table (lambda (x) (generic-method-table x)))
  756.       (defconstant internal-gf-name (lambda (x) (generic-name x)))
  757.       (defconstant internal-gf-discrimination-depth (lambda (x) (generic-discrimination-depth x)))
  758.       (defconstant internal-gf-method-lookup-function (lambda (x) (generic-method-lookup-function x)))
  759.       (defconstant internal-class-precedence-list (lambda (x) (class-precedence-list x)))
  760.  
  761.       (defun init-generic (gf)
  762.     (let ((lookup (simple-compute-method-lookup-function gf nil)))
  763.       ((setter generic-method-lookup-function) gf lookup)
  764.       ((setter generic-discriminator) gf
  765.        (std-generic-discriminator gf lookup))
  766.       ((setter generic-method-description) gf
  767.        (cons <method> nil))))
  768.  
  769.       (defun add-method-to-caches (gf sig meths)
  770.     ((setter generic-fast-cache) gf (cons sig meths))
  771.     (let ((table (generic-slow-cache gf)))
  772.       (if (null table)
  773.           ((setter generic-slow-cache)
  774.            gf
  775.            (make-initial-table sig (cons sig meths)))
  776.         (add-table-entry table sig (cons sig meths)))))
  777.  
  778.  
  779.       ))
  780.  
  781.   ;; lst -> (class (name position initarg ) ...)
  782. (defun make-fill-slot-list (classlist)
  783.     (cons 'list
  784.       (mapcar (lambda (classd)
  785.             `(list ,(scan-args 'name classd required-argument)
  786.                ,@(mapcar (lambda (slotd)
  787.                        `(list ,(scan-args 'class slotd (default-argument '<local-slot-description>))
  788.                           ',(scan-args 'name slotd null-argument)
  789.                           ,(scan-args 'position slotd null-argument)
  790.                           ',(scan-args 'initform slotd unbound-argument)
  791.                           ',(scan-args 'initarg slotd unbound-argument)))
  792.                      (scan-args 'direct-slot-descriptions classd required-argument))))
  793.           classlist)))
  794.  
  795. (defun make-slot-descriptions (classlist)
  796.     `(
  797.        ,@make-slot-descriptions-literals
  798.        (initialize-slots ,(make-fill-slot-list classlist))))
  799.  
  800.  
  801.   ;; NOTE: This form is NOT Pre-processed.
  802.  
  803.   (defconstant finalise-bootstrap-literals
  804.     '(
  805.  
  806.       ;; Define functions to avoid circularity in the bootstrap process
  807.  
  808.       (defun stable-generic-method-table (gf)
  809.     (if (eq (class-of gf) <generic-function>)
  810.         (internal-gf-method-table gf)
  811.       (generic-method-table gf)))
  812.  
  813.       (defun stable-generic-lookup-function (gf)
  814.     (if (eq (class-of gf) <generic-function>)
  815.         (internal-gf-method-lookup-function gf)
  816.       (generic-method-lookup-function gf)))
  817.  
  818.       (defun stable-generic-name (gf)
  819.     (if (eq (class-of gf) <generic-function>)
  820.         (internal-gf-name gf)
  821.       (generic-name gf)))
  822.  
  823.       (defun stable-generic-discrimination-depth (gf)
  824.     (if (eq (class-of gf) <generic-function>)
  825.         (internal-gf-discrimination-depth gf)
  826.       (generic-discrimination-depth gf)))
  827.  
  828.       (defun stable-class-precedence-list (cl)
  829.     ;;(generic_generic_prin\,Object (list 'stable-cpl cl) nil)
  830.     (if (eq (class-of cl) <class>)
  831.         (internal-class-precedence-list cl)
  832.       (class-precedence-list cl)))
  833.  
  834.       ;; Create other necessary generic functions
  835.  
  836.       (defconstant setter (simple-make-generic 'argtype 1
  837.                              'name 'setter))
  838.       (export setter)
  839.  
  840.  
  841.       (defconstant setter-setter (simple-make-generic 'argtype 2
  842.                                 'name 'setter-setter))
  843.       (export setter-setter)
  844.  
  845.       ;;(generic_generic_prin\,Object "Adding methiods to setter\n" nil)
  846.  
  847.       (simple-add-method setter-setter
  848.              (simple-make-method
  849.               'signature (list <generic-function> <object>)
  850.               'function internal-gf-setter-setter))
  851.  
  852.       (compile-time
  853.        (%Compiler-special-object add-property
  854.                  (setter-function t) setter)
  855.  
  856.        (%Compiler-special-object add-callback
  857.                  (setter-setter-function xx) setter-setter)
  858.  
  859.        (simple-add-method setter-setter
  860.               (simple-make-method
  861.                'signature (list <bytefunction> <object>)
  862.                'function (bf-setter bf-setter)))
  863.        )
  864.  
  865.       (simple-add-method setter
  866.              (simple-make-method
  867.               'signature (list <generic-function>)
  868.               'function internal-gf-setter))
  869.  
  870.       (compile-time
  871.        (simple-add-method setter
  872.               (simple-make-method
  873.                'signature (list <bytefunction>)
  874.                'function bf-setter))
  875.        )
  876.  
  877.       ;; generic-method restrictions
  878.       (defun generic-method-class (gf)
  879.     (car (generic-method-description gf)))
  880.  
  881.       (defun generic-method-domain (gf)
  882.     (cdr (generic-method-description gf)))
  883.  
  884.       (export generic-method-domain generic-method-class)
  885.  
  886.       (defun set-generic-method-description (gf class domain)
  887.     ((setter generic-method-description) gf (cons class domain)))
  888.  
  889.       (defconstant add-method-method
  890.     ;; XX:
  891.     (method-lambda (gf meth)
  892.                ;;(generic_generic_prin\,Object "add-method-method:" nil)
  893.                ;;(generic_generic_prin\,Object (generic-name gf) nil)
  894.                ;;(newline nil)
  895.                (if (= (generic-argtype gf) (list-length (method-signature meth)))
  896.                (let ((sig (restrict-method gf (method-signature meth)))
  897.                  (table (generic-method-table gf)))
  898.                  (if (null table)
  899.                  ((generic-setter generic-method-table)
  900.                   gf (make-initial-table sig (list meth)))
  901.                    (add-table-entry table sig (list meth)))
  902.                  (let ((true-depth (method-signature-depth gf meth)))
  903.                    (if (i-greaterp true-depth (generic-discrimination-depth gf))
  904.                    ((generic-setter generic-discrimination-depth) gf true-depth)
  905.                  nil))
  906.                  ((generic-setter generic-fast-cache) gf nil)
  907.                  ((generic-setter generic-slow-cache) gf nil)
  908.                  ((setter method-generic-function) meth gf)
  909.                  gf)
  910.              (error "add-method: argument mismatch" <Internal-Error> 'error-value (cons gf meth)))))
  911.       (export add-method-method)
  912.  
  913.  
  914.  
  915.       (defun trim-signature (gf sig)
  916.     (if (i-zerop (stable-generic-discrimination-depth gf))
  917.         nil
  918.       (labels ((add-obj (last lst n)
  919.                 (if (i-zerop n) nil
  920.                   (progn (let ((new  (cons (car lst) nil)))
  921.                        ((setter cdr) last new)
  922.                        (add-obj new (cdr lst) (i-sub1 n)))))))
  923.           (let ((first (cons (car sig) nil)))
  924.             (add-obj first (cdr sig) (i-sub1 (stable-generic-discrimination-depth gf)))
  925.             first))))
  926.  
  927.       ;; XXX: Boot problem
  928.       (defun find-applicable-methods (gf args)
  929.     (find-applic-methods-aux (stable-generic-method-table gf)
  930.                  (mapcar1 (lambda (x)
  931.                        (stable-class-precedence-list (class-of x)))
  932.                      args)))
  933.  
  934.       ;; wasteful...
  935.       (defun find-applic-methods-aux (table cpl-lst)
  936.     (if (null cpl-lst)
  937.         nil
  938.       (if (null (car cpl-lst))
  939.           nil
  940.         (let ((xx (assq (car (car cpl-lst)) table)))
  941.           (if (null xx)
  942.           (find-applic-methods-aux table
  943.                        (cons (cdr (car cpl-lst))
  944.                          (cdr cpl-lst)))
  945.         (if (null (cdr cpl-lst))
  946.             ;; found summat
  947.             (if (methodp (car (cdr xx)))
  948.             (cons (car (cdr xx))
  949.                   (find-applic-methods-aux table
  950.                                (cons (cdr (car cpl-lst))
  951.                                  (cdr cpl-lst))))
  952.               (progn
  953.             ;;(print "error-1")
  954.             ;;(print (list xx cpl-lst))
  955.             (cerror "yowzer" <Internal-Error> 'error-value xx)))
  956.           (append (find-applic-methods-aux (cdr xx) (cdr cpl-lst))
  957.               (find-applic-methods-aux table
  958.                            (cons (cdr (car cpl-lst))
  959.                              (cdr cpl-lst))))))))))
  960.  
  961.  
  962.       (deflocal debug nil)
  963.       ;;(defun set-debug (x) (setq debug x))
  964.       ;;(export set-debug)
  965.       ;; This is the TYPE_Generic only routine => cache handling is _bound_ to be ok.
  966.  
  967.       ;;(defun my-prin (x)
  968.       ;;(if (null (consp x))
  969.       ;;(prin-object x nil)
  970.       ;;(progn  (prin-object "(" nil) 
  971.       ;;(mapc (lambda (y) 
  972.       ;;(my-prin y))
  973.       ;;x)
  974.       ;;(prin-object ")" nil))))
  975.  
  976.       (defun find-and-call-generic (gf args)
  977.     ;;(prin-object "call " nil)
  978.     ;;(prin-object (symbol-name (primitive-slot-ref-0 gf)) nil)
  979.     ;;(my-prin args)
  980.     ;;(prin-object "\n" nil)
  981.     ;;(newline nil)
  982.     (let ((meths ((stable-generic-lookup-function gf) args))
  983.           (sig (mapcar1 class-of args)))
  984.       ;;(generic_generic_prin\,Object (list 'got-info meths sig) nil)
  985.       (if (null meths)
  986.           (error "No applicable methods" no-applicable-method
  987.              'error-value gf
  988.              'sig sig
  989.              'args args)
  990.         (let ((trimmed-sig (trim-signature gf sig)))
  991.           ;;(generic_generic_prin\,Object trimmed-sig nil)
  992.           ;;(set-bc-global 3 t)
  993.           (add-method-to-caches gf trimmed-sig meths)
  994.           (call-method-by-list meths args)))))
  995.  
  996.       ;; called by add-method-method.
  997.       ;; Forces method signatures to be a subset of the domain of the function.
  998.       ;; It deliberately allows methods on superclasses of elts of the domain---
  999.       ;; makes defmethod easier.
  1000.       (defun restrict-method (gf sig)
  1001.     (let ((domain (generic-method-domain gf)))
  1002.       ;;(generic_generic_prin\,Object domain nil)
  1003.       (if (null domain) sig
  1004.         (labels ((restrict-lsts (sig dom)
  1005.                     (if (null sig) nil
  1006.                       (if (subclassp (car sig) (car dom))
  1007.                       (cons (car sig)
  1008.                         (restrict-lsts (cdr sig) (cdr dom)))
  1009.                     (if (subclassp (car dom) (car sig))
  1010.                         (cons (car dom)
  1011.                           (restrict-lsts (cdr sig) (cdr dom)))
  1012.                       (progn (error "Add-method: outside domain" <Internal-Error>)
  1013.                          2))))))
  1014.             (restrict-lsts sig domain)))))
  1015.  
  1016.       ;; now set it up...
  1017.  
  1018.       ;; shove new version of gf into place...
  1019.       (set-compute-and-apply-fn find-and-call-generic)
  1020.       (compile-time
  1021.       (set-bc-global 0 find-and-call-generic)
  1022.       )
  1023.  
  1024.       (compile-time
  1025.        (defun make (x . l)
  1026.      (initialize (allocate x l) l))
  1027.        (export make)
  1028.        )
  1029.       (defconstant add-method (simple-make-generic 'argtype 2 'lambda-list '(object lst) 'name 'add-method))
  1030.       (export add-method)
  1031.  
  1032.       (defconstant compute-method-lookup-function
  1033.     (simple-make-generic 'argtype 2 'lambda-list '(object lst) 'name 'compute-method-lookup-function))
  1034.       (export compute-method-lookup-function)
  1035.  
  1036.       (defconstant compute-discriminating-function
  1037.     (simple-make-generic 'argtype 4 'lambda-list '(object lst object object) 'name 'compute-discriminating-function))
  1038.       (export compute-discriminating-function)
  1039.  
  1040.       (defconstant =
  1041.     (simple-make-generic 'argtype 2 'lambda-list '(x y) 'name '=))
  1042.       (export =)
  1043.  
  1044.       ;; Bootstrap methods
  1045.       (defconstant std-allocate-object
  1046.     (method-lambda (a b)
  1047.                (allocate-object a)))
  1048.  
  1049.       ;; the standard method on init-instance
  1050.       (defconstant std-initialize-object
  1051.     (method-lambda (obj initlist)
  1052.                ;;(generic_generic_prin\,Object (cons (class-name (class-of obj))
  1053.                ;;  initlist)
  1054.                ;;                 nil)
  1055.                (initialize-local-slots obj initlist)
  1056.                (mapc1 (lambda (slot)
  1057.                    (let ((initarg (slot-description-initarg slot))
  1058.                      (initfunction (slot-description-initfunction slot)))
  1059.                  (if (eq initarg unbound-slot-value)
  1060.                      (if (eq initfunction unbound-slot-value)
  1061.                      nil
  1062.                        ((slot-description-slot-writer slot) obj (initfunction)))
  1063.                    (let ((value (scan-args initarg initlist unbound-argument)))
  1064.                      (if (eq value unbound-slot-value)
  1065.                      (if (eq initfunction unbound-slot-value)
  1066.                          nil
  1067.                        ((slot-description-slot-writer slot) obj (initfunction)))
  1068.                        ((slot-description-slot-writer slot) obj value)))))
  1069.                    )
  1070.                  (class-non-local-slot-descriptions (class-of obj)))
  1071.                obj))
  1072.  
  1073.       ;;(generic_generic_prin\,Object "** Initing generics\n" nil)
  1074.       ;; for previously allocated generics...
  1075.  
  1076.  
  1077.       (init-generic allocate)
  1078.       (init-generic initialize)
  1079.       (init-generic generic-write)
  1080.       (init-generic generic-prin)
  1081.       (init-generic output)
  1082.       (init-generic generic-read)
  1083.       (init-generic flush)
  1084.  
  1085.       (init-generic binary+)
  1086.       (init-generic binary-)
  1087.       (init-generic binary*)
  1088.       (init-generic binary/)
  1089.       (init-generic binary-gcd)
  1090.       (init-generic binary-lcm)
  1091.       (init-generic binary<)
  1092.       (init-generic negate)
  1093.       (init-generic equal)
  1094.  
  1095.       ;;(prin-object "** Initted generics\n" nil)
  1096.  
  1097.       (simple-add-method add-method (simple-make-method 'signature (list <generic-function> <method>)
  1098.                             'function add-method-method))
  1099.  
  1100.  
  1101.       (simple-add-method =
  1102.              (simple-make-method
  1103.               'signature (list <fixint> <fixint>)
  1104.               'function binary=_Integer))
  1105.  
  1106.       ;;(prin-object "** Initted add-method-method\n" nil)
  1107.       ;; First generic call
  1108.  
  1109.       (add-method allocate
  1110.           (simple-make-method 'signature (list <class> <object>)
  1111.                       'function std-allocate-object))
  1112.  
  1113.       ;;(prin-object "** Done Gcall\n" nil)
  1114.       (add-method initialize
  1115.           (simple-make-method 'signature (list <object> <object>)
  1116.                       'function std-initialize-object))
  1117.  
  1118.       ;;(prin-object "** Done init\n" nil)
  1119.       (add-method initialize
  1120.           (simple-make-method 'signature (list <method> <object>)
  1121.                       'function (method-lambda (a b)
  1122.                                    (let ((new (call-next-method)))
  1123.                                  ((setter method-signature) a
  1124.                                   (scan-args 'signature b
  1125.                                          required-argument))
  1126.                                  (set-type new method-type)
  1127.                                  new))))
  1128.  
  1129.       ;;(generic_generic_prin\,Object "** Done Gcall\n" nil)
  1130.       (add-method initialize
  1131.           (simple-make-method
  1132.            'signature (list <generic-function> <object>)
  1133.            'function (method-lambda (a initargs)
  1134.                         (let ((new (call-next-method)))
  1135.                           ((generic-setter generic-slow-cache) new nil)
  1136.                           ((generic-setter generic-fast-cache) new nil)
  1137.                           ((generic-setter generic-method-table) new nil)
  1138.                           (if (eq (generic-argtype new) unbound-slot-value)
  1139.                           ((setter generic-argtype) new
  1140.                            (list-length (scan-args 'lambda-list initargs
  1141.                                        required-argument)))
  1142.                         nil)
  1143.                           (let ((domain (scan-args 'domain initargs null-argument)))
  1144.                         (let ((lookup-fn
  1145.                                (compute-method-lookup-function new domain))
  1146.                               (methods (scan-args 'methods initargs null-argument))
  1147.                               (method-class (scan-args 'method-class initargs
  1148.                                            (default-argument <method>))))
  1149.                           ((setter generic-method-lookup-function) new lookup-fn)
  1150.                           (let ((disc-fun
  1151.                              (compute-discriminating-function new domain lookup-fn
  1152.                                               methods))
  1153.                             (disc-methods (find-applicable-methods
  1154.                                        compute-discriminating-function
  1155.                                        (list new domain lookup-fn methods))))
  1156.                             ((setter generic-discriminator) new disc-fun)
  1157.                             (if (eq (car disc-methods) std-discrimination-method)
  1158.                             (set-type new generic-type)
  1159.                               nil))
  1160.                           (set-generic-method-description new method-class domain)
  1161.                           ((generic-setter generic-discrimination-depth) new 0)
  1162.                           (mapc1 (lambda (meth) (add-method new meth)) methods)))
  1163.                           new))))
  1164.  
  1165.       ;;(generic_generic_prin\,Object "** Done init (generic)\n" nil)
  1166.       (add-method compute-method-lookup-function
  1167.           (simple-make-method 'signature (list <generic-function> <object>)
  1168.                       'function (method-lambda (gf domain)
  1169.                                    (lambda (args)
  1170.                                  (find-applicable-methods gf args)))))
  1171.  
  1172.       ;; Notes:
  1173.       ;; This method can assume that it is working on class discrimination,
  1174.       ;; rather than instances. Thus the internal caching techniques are
  1175.       ;; entirely cool, and perhaps should be used.
  1176.       (defconstant std-discrimination-method
  1177.     (simple-make-method 'signature (list <generic-function> <object> <object> <object>)
  1178.                 'function (method-lambda (gf dom lookup meths)
  1179.                              (lambda (args)
  1180.                                (let ((meths (lookup args)))
  1181.                              (if (null meths)
  1182.                                  (error "No applicable method" no-applicable-method
  1183.                                     'error-value gf
  1184.                                     'sig (mapcar1 class-of args))
  1185.                                (call-method-by-list meths args)))))))
  1186.  
  1187.       (add-method compute-discriminating-function
  1188.           std-discrimination-method)
  1189.  
  1190.       ;; This is the internal algorithm.
  1191.       ;;       Unless you want caching, there is no point using it
  1192.       ;;(defconstant std-discrimination-method
  1193.       ;;(simple-make-method 'signature (list <generic-function> <object> <object> <object>)
  1194.       ;;                    'function (method-lambda (gf dom lookup-fn meths)
  1195.       ;; (lambda (args)
  1196.       ;;   (let ((fast-cache (generic-fast-cache gf)))
  1197.       ;;     (labels ((fast-lookup (cache lst)
  1198.       ;;               ;;(format t "fast: ~a~%" cache)
  1199.       ;;               (if (null cache)
  1200.       ;;                   (progn ;; (format t "fast success: ~a~%" (cdr fast-cache))
  1201.       ;;                      (call-method-by-list (cdr fast-cache) args))
  1202.       ;;                 (if (eq (car cache) (class-of (car lst)))
  1203.       ;;                 (fast-lookup (cdr cache) (cdr lst))
  1204.       ;;                   (slow-lookup (generic-slow-cache gf)
  1205.       ;;                        (generic-discrimination-depth gf)
  1206.       ;;                        args))))
  1207.       ;;          (slow-lookup (cache n lst)
  1208.       ;;               ;;(format t "slow: ~a~%" cache)
  1209.       ;;               (if (> n 0)
  1210.       ;;                   (if (null cache) (lookup)
  1211.       ;;                 (if (eq (car (car cache))
  1212.       ;;                     (class-of (car lst)))
  1213.       ;;                     (slow-lookup (cdr (car cache))
  1214.       ;;                          (- n 1)
  1215.       ;;                          (cdr lst))
  1216.       ;;                   (slow-lookup (cdr cache) n lst)))
  1217.       ;;                 (progn ((setter generic-fast-cache) gf cache)
  1218.       ;;                    ;;(format t "Slow success: ~a~%" (cdr cache))
  1219.       ;;                    (call-method-by-list (cdr cache) args))))
  1220.       ;;          (lookup ()
  1221.       ;;              (let ((meths (lookup-fn args)))
  1222.       ;;            (if (null meths)
  1223.       ;;                (error "No applicable method" no-applicable-method
  1224.       ;;                   'error-value gf
  1225.       ;;                   'sig (mapcar class-of args))
  1226.       ;;              (progn
  1227.       ;;                (add-method-to-caches gf (trim-signature gf (mapcar class-of args)) meths)
  1228.       ;;                (call-method-by-list meths args))))))
  1229.       ;;         (if fast-cache
  1230.       ;;         (fast-lookup (car fast-cache) args)
  1231.       ;;           (lookup))))))))
  1232.  
  1233.       ;; 1st generic call to allocate+initialize
  1234.       (add-method generic-prin
  1235.           (make <method>
  1236.             'signature (list <object> <object>)
  1237.             'function prin-object))
  1238.  
  1239.       ;;(add-method generic-prin
  1240.       ;;  (make <method> 'signature (list <pair> <object>)
  1241.       ;;       'function generic_generic_prin\,Cons))
  1242.  
  1243.       (add-method generic-write
  1244.           (make <method>
  1245.             'signature (list <object> <object>)
  1246.             'function  (method-lambda (x y)
  1247.                           (generic-prin x y))))
  1248.  
  1249.       (add-method flush
  1250.           (make <method>
  1251.             'signature (list <object>)
  1252.             'function  (method-lambda (y) nil)))
  1253.                           
  1254.  
  1255.       ;; classes to fix up later
  1256.  
  1257.       (deflocal no-applicable-method ())
  1258.  
  1259.       (defun set-no-applicable-method (x)
  1260.     (setq no-applicable-method x))
  1261.  
  1262.       (export set-no-applicable-method)
  1263.  
  1264.       (add-method allocate
  1265.           (make <method>
  1266.             'signature (list <primitive-class> <object>)
  1267.             'function (method-lambda (c l)
  1268.                          (error "Cannot allocate primitive class"
  1269.                             <Internal-Error>
  1270.                             'error-value c))))
  1271.       ;; Copy
  1272.       (defconstant copy
  1273.     (make <generic-function>
  1274.           'lambda-list '(x)
  1275.           'argtype 1
  1276.           'name 'copy
  1277.           'method-class <method>))
  1278.  
  1279.       (add-method copy
  1280.           (make <method>
  1281.             'signature (list <pair>)
  1282.             'function (method-lambda (x)
  1283.                          (cons (car x)
  1284.                                (cdr x)))))
  1285.  
  1286.  
  1287.       (add-method copy
  1288.           (make <method>
  1289.             'signature (list (class-of nil))
  1290.             'function (method-lambda (x) nil)))
  1291.  
  1292.       ;; I don't want a method on Object!
  1293.       (add-method copy
  1294.           (make <method>
  1295.             'signature (list <structure>)
  1296.             'function 
  1297.             (method-lambda (x)
  1298.                        (labels ((copy-slots (old new slot-list)
  1299.                                 (if (null slot-list) nil
  1300.                                   (progn ((slot-description-slot-writer (car slot-list))
  1301.                                       new ((slot-description-slot-reader (car slot-list)) new))
  1302.                                      (copy-slots old new (cdr slot-list))))))
  1303.                            (copy-slots x (allocate (class-of x) nil)
  1304.                                (class-slot-descriptions x))))))
  1305.  
  1306.       (add-method copy
  1307.           (make <method>
  1308.             'signature (list <symbol>)
  1309.             'function identity))
  1310.  
  1311.       (add-method copy (make <method>
  1312.                  'signature (list <vector>)
  1313.                  'function generic_copy\,Vector))
  1314.       (export copy)
  1315.       ;; Hashing
  1316.  
  1317.       (defconstant generic-hash
  1318.     (make <generic-function>
  1319.           'lambda-list '(x)
  1320.           'argtype 1
  1321.           'name 'generic-hash
  1322.           'method-class <method>))
  1323.  
  1324.       (add-method generic-hash
  1325.           (make <method>
  1326.             'signature (list <i-function>)
  1327.             'function (method-lambda (x)
  1328.                     99)))
  1329.  
  1330.       (add-method generic-hash
  1331.           (make <method>
  1332.             'signature (list <object>)
  1333.             'function (method-lambda (x)
  1334.                     0)))
  1335.  
  1336.       (set-standard-tab-functions generic-hash eq)
  1337.  
  1338.       (export generic-hash)
  1339.  
  1340.       ;; Setters and the like...
  1341.  
  1342.  
  1343.       (defconstant i-function-setters (make-table ()))
  1344.  
  1345.       (defconstant i-setter
  1346.     (method-lambda (x)
  1347.                (let ((xx (sys-table-ref i-function-setters x)))
  1348.              (if (functionp xx)
  1349.                  xx
  1350.                (error "Setter: no setter for function" <Internal-Error> 'error-value x)))))
  1351.  
  1352.       (defconstant i-setter-setter
  1353.     (method-lambda (x y)
  1354.                (if (if (functionp x)
  1355.                    (if (functionp y) t nil) nil)
  1356.                ((setter sys-table-ref) i-function-setters x y)
  1357.              (error "Bad setter" <Internal-Error> 'error-value (cons x y)))))
  1358.  
  1359.       (add-method setter
  1360.           (make <method>
  1361.             'signature (list <i-function>)
  1362.             'function i-setter))
  1363.  
  1364.       (add-method setter
  1365.           (make <method>
  1366.             'signature (list <c-function>)
  1367.             'function c-setter))
  1368.  
  1369.       (add-method setter-setter
  1370.           (make <method>
  1371.             'signature (list <i-function> <object>)
  1372.             'function i-setter-setter))
  1373.  
  1374.       (add-method setter-setter
  1375.           (make <method>
  1376.             'signature (list <c-function> <object>)
  1377.             'function c-setter-setter))
  1378.  
  1379.       ;; I know it looks nasty....
  1380.       (setter-setter setter setter-setter)
  1381.  
  1382.       ;; errors
  1383.       (defconstant error
  1384.     (lambda (message type . junk)
  1385.       (let ((lst (cons 'message (cons message junk))))
  1386.         (internal-signal (initialize (allocate type lst) lst)
  1387.                  nil))))
  1388.  
  1389.     (defconstant cerror
  1390.       (lambda (message type . junk)
  1391.         (let ((lst (cons 'message (cons message junk))))
  1392.           (simple-call/cc
  1393.            (lambda (cont)
  1394.          (internal-signal (initialize (allocate type lst) lst)
  1395.                   cont))))))
  1396.  
  1397.       (export error cerror)  
  1398.       
  1399.       (compile-time 
  1400.        (defun apply (fn a1 . rest)
  1401.      (labels ((aux (last rest)
  1402.                (if (cdr rest)
  1403.                (let ((next (cons (car rest) nil)))
  1404.                  ((setter cdr) last next)
  1405.                  (aux next (cdr rest)))
  1406.              (if (if (car rest) (consp (car rest)) t)
  1407.                  ((setter cdr) last (car rest))
  1408.                (error "apply: last arg must be a list" <Internal-Error> 'error-value (car rest))))))
  1409.          (if rest
  1410.              (let ((first (cons a1 nil)))
  1411.                (aux first rest)
  1412.                (%do-apply fn first))
  1413.            (if (consp a1) 
  1414.                (%do-apply fn a1)
  1415.              (if (null a1)
  1416.              (%do-apply fn nil)
  1417.                (error "apply: arg must be a list" <Internal-Error> 'error-value a1))))))
  1418.        (export apply)
  1419.        )
  1420.  
  1421.  
  1422.       ;; Integer Methods. Needed by telos
  1423.       (add-method binary+ (make <method>
  1424.                 'signature (list <fixint> <fixint>)
  1425.                 'function binary+_Integer))
  1426.  
  1427.       (add-method binary- (make <method>
  1428.                      'signature (list <fixint> <fixint>)
  1429.                      'function binary-_Integer))
  1430.  
  1431.       (add-method binary* (make <method>
  1432.                      'signature (list <fixint> <fixint>)
  1433.                      'function binary*_Integer))
  1434.  
  1435.       (add-method binary/ (make <method>
  1436.                      'signature (list <fixint> <fixint>)
  1437.                      'function binary/_Integer))
  1438.  
  1439.       (add-method binary-lcm (make <method>
  1440.                         'signature (list <fixint> <fixint>)
  1441.                         'function binary-lcm-integer))
  1442.  
  1443.       (add-method binary-gcd (make <method>
  1444.                         'signature (list <fixint> <fixint>)
  1445.                         'function binary-gcd-integer))
  1446.  
  1447.       (add-method binary< (make <method>
  1448.                      'signature (list <fixint> <fixint>)
  1449.                      'function binary<_Integer))
  1450.  
  1451.       (add-method negate (make <method>
  1452.                     'signature (list <fixint>)
  1453.                     'function negate-integer))
  1454.  
  1455. (compile-time
  1456.   (defun mapcar  (fn l1 . others)
  1457.     (if (null others)
  1458.     (mapcar1 fn l1)
  1459.       (let ((allargs (cons l1 (copy-list others))))
  1460.     (labels ((step-lists (result last)
  1461.                  (let ((next (get-new-lsts allargs)))
  1462.                    (if (null next)
  1463.                    result
  1464.                  (let ((new (list (apply fn next))))
  1465.                    (if (null result)
  1466.                        (step-lists new new)
  1467.                      (progn ((setter cdr) last new)
  1468.                         (step-lists result new)))))))
  1469.          (get-new-lsts1 (arglst lastarg)
  1470.                    (if (null arglst) t
  1471.                  (if (null (car arglst)) nil
  1472.                    (let ((new (cons (car (car arglst)) nil)))
  1473.                      ((setter cdr) lastarg new)
  1474.                      ((setter car) arglst (cdr (car arglst)))
  1475.                      (get-new-lsts1 (cdr arglst) new)))))
  1476.          (get-new-lsts (args)
  1477.                    (if (null (car args)) nil
  1478.                  (let ((newargs (cons (car (car args)) nil)))
  1479.                    ((setter car) args (cdr (car args)))
  1480.                    (if (get-new-lsts1 (cdr args) newargs)
  1481.                        newargs
  1482.                      nil)))))
  1483.         (step-lists nil nil)))))
  1484.   
  1485.   (defun mapc  (fn l1 . others)
  1486.     (if (null others)
  1487.     (mapc1 fn l1)
  1488.       (let ((allargs (cons l1 (copy-list others))))
  1489.     (labels ((step-lists ()
  1490.                  (let ((next (get-new-lsts allargs)))
  1491.                    (if (null next)
  1492.                    nil
  1493.                  (progn (apply fn next)
  1494.                     (step-lists)))))
  1495.          (get-new-lsts1 (arglst lastarg)
  1496.                    (if (null arglst) t
  1497.                  (if (null (car arglst)) nil
  1498.                    (let ((new (cons (car (car arglst)) nil)))
  1499.                      ((setter cdr) lastarg new)
  1500.                      ((setter car) arglst (cdr (car arglst)))
  1501.                      (get-new-lsts1 (cdr arglst) new)))))
  1502.          (get-new-lsts (args)
  1503.                    (if (null (car args)) nil
  1504.                  (let ((newargs (cons (car (car args)) nil)))
  1505.                    ((setter car) args (cdr (car args)))
  1506.                    (if (get-new-lsts1 (cdr args) newargs)
  1507.                        newargs
  1508.                      nil)))))
  1509.         (step-lists)))))
  1510.  
  1511.   (export mapc mapcar)
  1512.  
  1513.  
  1514.   )
  1515.       ))
  1516.  
  1517.   (defun method-initialisation-code (classlist)
  1518.     finalise-bootstrap-literals)
  1519.  
  1520.  
  1521.  
  1522.   ;; end module
  1523. )
  1524.  
  1525.